﻿using System.Windows.Controls;
using System.Net.Http;
using System.Windows;
using System;
using System.Windows.Media.Imaging;
using System.Text.RegularExpressions;
using System.Data.SQLite;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Threading;

namespace checkVisit
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private System.Windows.Forms.NotifyIcon icon;
        // 数据库连接
        SQLiteConnection m_dbConnection;

        
        public MainWindow()
        {
            InitializeComponent();
            //链接数据库
            ConnectDB();
            // 初始化列表
            InitalzeListView();

            // 显示任务栏图标
            ShowNotifyIcon();

            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(30);
            timer.Tick += KeepUpdate;
            timer.Start();




        }


       

        void ShowNotifyIcon()
        {
            icon = new System.Windows.Forms.NotifyIcon();
            icon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(System.Windows.Forms.Application.ExecutablePath);
            icon.Text = "Checking website access";
            icon.Visible = true;

            icon.ContextMenu = new System.Windows.Forms.ContextMenu(new[]
            {
                new System.Windows.Forms.MenuItem("hide window",(sender, args) =>
                {
                    Visibility = System.Windows.Visibility.Hidden;
                    ShowInTaskbar = false;
                }),
                new System.Windows.Forms.MenuItem("show windows",(sender,args) =>
                {
                    Visibility = System.Windows.Visibility.Visible;
                    ShowInTaskbar = true;
                    Activate();
                      //将窗体变为正常化
                this.WindowState = WindowState.Normal;
                }),
                new System.Windows.Forms.MenuItem("add to startup",(sender, args) =>
                {
                      try
                      {
                          Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                          Assembly curAssembly = Assembly.GetExecutingAssembly();
                          key.SetValue(curAssembly.GetName().Name, curAssembly.Location);
                      }
                      catch
                     {

                      }
                }),
                new System.Windows.Forms.MenuItem("remove from startup",(sender, args) =>
                {
                     try
                      {
                          Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                          Assembly curAssembly = Assembly.GetExecutingAssembly();
                          key.DeleteValue(curAssembly.GetName().Name);

                      }
                      catch (Exception e)
                     {
                        MessageBox.Show("error:"+e.Message);
                      }

                })
                ,
                  new System.Windows.Forms.MenuItem("quit",(sender,args) =>
                {
                    System.Windows.Application.Current.Shutdown();
                })
            });

            icon.MouseDoubleClick += (sender, agrs) =>
            {
                Visibility = System.Windows.Visibility.Visible;
                ShowInTaskbar = true;
                Activate();
                //将窗体变为正常化
                this.WindowState = WindowState.Normal;
            };


        }

        private void CreateDatabase()
        {
            //var currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            //MessageBox.Show(currentPath);
            SQLiteConnection.CreateFile("WL.sqlite");
        }

        private void ConnectDB()
        {
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WL.sqlite");
           
            string sqlite = $"Data Source={path};Version=3;";
      
            m_dbConnection = new SQLiteConnection(sqlite);
            m_dbConnection.Open();
        }

        void CreateTable()
        {
            string sql = "create table websitelist (url varchar(100))";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();
        }

        void AddUrl(string url)
        {
            string sql = $"insert into websitelist (url) values ('{url}')";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            command.ExecuteNonQuery();
        }

        bool SelectUrl(string url)
        {
            bool result = false;
            string sql = $"select * from websitelist where url = '{url}'";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            SQLiteDataReader reader = command.ExecuteReader();
            if (reader.HasRows == true)
            {
                result = true;
            }

            return result;
        }

        void InitalzeListView()
        {
            try
            {
              
                string sql = "select * from websitelist";
                SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
                SQLiteDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    LoadWebsite(reader["url"].ToString());
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("error from Initialize:" + e.Message);
            }
           

        }
         
        void DeleteFromDB(string url)
        {
            string sql = "delete from websitelist where url = '"+ url + "'";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);

            command.ExecuteNonQuery();
        }
        delegate void LoadWebsiteCallBack(string url);
        private async void LoadWebsite(string url)
        {
            if (!CheckAccess())
            {
                Dispatcher.Invoke(new LoadWebsiteCallBack(LoadWebsite), url);
                return;
            }
            else
            {
               
                List<string> all_items = new List<string>();

                for (int i = 0;i <websiteList.Items.Count; i++)
                {
                    var selectObj = websiteList.Items[i] as ListViewItem;
                    var itempanel = selectObj.Content as StackPanel;
                    var itemValue = itempanel.Children[1] as TextBlock;

                    all_items.Add(itemValue.Text);
                }

                // 如果在数据库中有就，并且也在listview中
                if (SelectUrl(url) == true && all_items.Contains(url) == true)
                {

                    for (int i = 0; i < websiteList.Items.Count; i++)
                    {
                        var selectObj = websiteList.Items[i] as ListViewItem;
                        var itempanel = selectObj.Content as StackPanel;
                        var itemValue = itempanel.Children[1] as TextBlock;

                        if (itemValue.Text == url)
                        {
                           
                            try
                            {
                              
                                var response = await client.GetAsync(url);

                                if (response.StatusCode.ToString() == "OK")
                                {
                                    var image = itempanel.Children[0] as Image;
                                    BitmapImage bi3 = new BitmapImage();
                                    bi3.BeginInit();
                                    bi3.UriSource = new Uri("/images/green.png", UriKind.Relative);
                                    bi3.EndInit();
                                    image.Source = bi3;
                                }

                            }
                           
                           catch 
                            {
                                    MessageBox.Show($"{url} is currently out of access");
                                    var image = itempanel.Children[0] as Image;
                                    BitmapImage bi3 = new BitmapImage();
                                    bi3.BeginInit();
                                    bi3.UriSource = new Uri("/images/red.png", UriKind.Relative);
                                    bi3.EndInit();
                                    image.Source = bi3;
                                
                            }

                        }

                    }


                }else if (SelectUrl(url) == true && all_items.Contains(url) == false)
                {
                    try
                    {
                       
                        var response = await client.GetAsync(url);

                        if (response.StatusCode.ToString() == "OK")
                        {

                            StackPanel panel = new StackPanel();
                            Image image = new Image();

                            BitmapImage bi3 = new BitmapImage();
                            bi3.BeginInit();
                            bi3.UriSource = new Uri("/images/green.png", UriKind.Relative);
                            bi3.EndInit();
                            image.Source = bi3;
                            panel.Children.Add(image);
                            panel.Children.Add(new TextBlock { Text = url });
                            panel.Orientation = Orientation.Horizontal;

                            websiteList.Items.Add(new ListViewItem { Content = panel });
                        }

                    }

                    catch 
                    {
                        StackPanel panel = new StackPanel();
                        Image image = new Image();

                        BitmapImage bi3 = new BitmapImage();
                        bi3.BeginInit();
                        bi3.UriSource = new Uri("/images/red.png", UriKind.Relative);
                        bi3.EndInit();
                        image.Source = bi3;
                        panel.Children.Add(image);
                        panel.Children.Add(new TextBlock { Text = url });
                        panel.Orientation = Orientation.Horizontal;

                        websiteList.Items.Add(new ListViewItem { Content = panel });

                    }

                    all_items.Clear();
                }














            }


        }
        
        
        // httpclient实例
        private static readonly HttpClient client = new HttpClient();

        private void AddBtn_Click(object sender, RoutedEventArgs e)
        {
            var url = websiteInput.Text;
            bool check = CheckUrl(url);
         
            if (url.Length == 0)
            {
                MessageBox.Show("Url field can't be empty");
            }
            else if (check != true)
            {
                MessageBox.Show($"{url} is not a valid url,it should be https or http://abc.example.com");
            }
            else 
            {
                CheckAndAdd(url);
            }

        }

        private void DeleteBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var selected = websiteList.SelectedItem;
                var selectObj = selected as ListViewItem;
                var panel = selectObj.Content as StackPanel;
                var removeItem = panel.Children[1] as TextBlock;
                MessageBoxResult result = MessageBox.Show($"Are you sure to delete { removeItem.Text}?", "Warning", MessageBoxButton.YesNo);
              
                if (result.ToString() == "No")
                {
                    return;
                }
                else
                {
                    websiteList.Items.Remove(selected);
                    DeleteFromDB(removeItem.Text);
                }


            }
            catch (System.ArgumentOutOfRangeException)
            {
                MessageBox.Show("You haven't select any website yet.");
            }
            catch (System.NullReferenceException)
            {
                MessageBox.Show("You haven't select any website yet.");
            }
            
           
        }

        private bool CheckUrl(string url)
        {
            bool result = true;
            string Pattern = @"^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&$%\$#\=~])*$";
            Regex r = new Regex(Pattern);
            string source = url;
            Match m = r.Match(source);
            if (m.Success)
            {
                result = true;
            }
            else
            {
                result = false;
            }

            return result;
        }

        private async void CheckAndAdd(string url)
        {
            
            try
            {
               
                var response = await client.GetAsync(url);

                if (response.StatusCode.ToString() == "OK")
                {
                    List<string> all_items = new List<string>();

                    foreach (ListViewItem item in websiteList.Items)
                    {
                        var selectObj = item as ListViewItem;
                        var itempanel = selectObj.Content as StackPanel;
                        var itemValue = itempanel.Children[1] as TextBlock;

                        all_items.Add(itemValue.Text);
                    }

                    if (all_items.Contains(url))
                    {
                        MessageBox.Show($"You already have {url} in monitoring list");
                    }
                    else
                    {

                        StackPanel panel = new StackPanel();
                        Image image = new Image();

                        BitmapImage bi3 = new BitmapImage();
                        bi3.BeginInit();
                        bi3.UriSource = new Uri("/images/green.png", UriKind.Relative);
                        bi3.EndInit();
                        image.Source = bi3;
                        panel.Children.Add(image);
                        panel.Children.Add(new TextBlock { Text = url });
                        panel.Orientation = Orientation.Horizontal;

                        websiteList.Items.Add(new ListViewItem { Content = panel });

                        AddUrl(url);

                    }





                }
                else
                {
                    List<string> all_items = new List<string>();

                    foreach (ListViewItem item in websiteList.Items)
                    {
                        var selectObj = item as ListViewItem;
                        var itempanel = selectObj.Content as StackPanel;
                        var itemValue = itempanel.Children[1] as TextBlock;

                        all_items.Add(itemValue.Text);
                    }

                    if (all_items.Contains(url))
                    {
                        MessageBox.Show($"You already have {url} in monitoring list");
                    }
                    else
                    {

                        StackPanel panel = new StackPanel();
                        Image image = new Image();

                        BitmapImage bi3 = new BitmapImage();
                        bi3.BeginInit();
                        bi3.UriSource = new Uri("/images/red.png", UriKind.Relative);
                        bi3.EndInit();
                        image.Source = bi3;
                        panel.Children.Add(image);
                        panel.Children.Add(new TextBlock { Text = url });
                        panel.Orientation = Orientation.Horizontal;

                        websiteList.Items.Add(new ListViewItem { Content = panel });

                        AddUrl(url);

                    }
                }
            }
            catch (System.Net.Http.HttpRequestException)
            {
                List<string> all_items = new List<string>();

                foreach (ListViewItem item in websiteList.Items)
                {
                    var selectObj = item as ListViewItem;
                    var itempanel = selectObj.Content as StackPanel;
                    var itemValue = itempanel.Children[1] as TextBlock;

                    all_items.Add(itemValue.Text);
                }

                if (all_items.Contains(url))
                {
                    MessageBox.Show($"You already have {url} in monitoring list");
                }
                else
                {

                    StackPanel panel = new StackPanel();
                    Image image = new Image();

                    BitmapImage bi3 = new BitmapImage();
                    bi3.BeginInit();
                    bi3.UriSource = new Uri("/images/red.png", UriKind.Relative);
                    bi3.EndInit();
                    image.Source = bi3;
                    panel.Children.Add(image);
                    panel.Children.Add(new TextBlock { Text = url });
                    panel.Orientation = Orientation.Horizontal;

                    websiteList.Items.Add(new ListViewItem { Content = panel });

                    AddUrl(url);

                }
            }
        
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            
        }

        delegate void KeepUpdateCallback();

        private async void KeepUpdate(object sender, EventArgs e)
        {

            await Task.Run(async () =>
            {
                await Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
                {

                    for (int i = 0;i< websiteList.Items.Count;i++)
                    {
                        var selectObj = websiteList.Items[i] as ListViewItem;
                        var itempanel = selectObj.Content as StackPanel;
                        var itemValue = itempanel.Children[1] as TextBlock;
                        string eurl = itemValue.Text;

                        await Task.Run(() => LoadWebsite(eurl));

                        //Thread t = new Thread(() => LoadWebsite(eurl));
                        //t.Start();

                        //LoadWebsite(itemValue.Text);
                    }

                }));

            });




            }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
           
            //取消关闭窗体
            e.Cancel = true;
            //将窗体变为最小化
            this.WindowState = WindowState.Minimized;
            //不显示在系统任务栏
            this.ShowInTaskbar = false;
        }


    }

}

